program ParserTest;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ResConst in '..\..\trunk\src\General\ResConst.pas',
  Contnrs,
  CPVariables in '..\..\trunk\src\Parser\CPVariables.pas',
  CPTokenizer in '..\..\trunk\src\Parser\CPTokenizer.pas',
  CPToken in '..\..\trunk\src\Parser\CPToken.pas',
  CPStringHashMap in '..\..\trunk\src\Parser\CPStringHashMap.pas',
  CPParserBase in '..\..\trunk\src\Parser\CPParserBase.pas',
  CPParser in '..\..\trunk\src\Parser\CPParser.pas',
  CPInstructions in '..\..\trunk\src\Parser\CPInstructions.pas',
  CPDefaultBuiltinFunctions in '..\..\trunk\src\Parser\CPDefaultBuiltinFunctions.pas',
  CPBuiltinFunctions in '..\..\trunk\src\Parser\CPBuiltinFunctions.pas',
  Math,
  CPNoise in '..\..\trunk\src\Parser\CPNoise.pas',
  StopWatch in '..\..\trunk\src\General\StopWatch.pas';

var
  LongEquation: string =
  '(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))' +
  '/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/' +
  '((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-' +
  'e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6' +
  '+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e' +
  '*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)';

procedure TestPerformance;
const
  IterationCount = 100000;
var
  I: Integer;
  Parser2: TCPParser;
  Instructions: TCPInstructionList;
begin
  Instructions := nil;

  Watch.Reset;
  Parser2 := TCPParser.Create;
    for I  := 1 to 1 do
    begin
      Instructions.Free;
      Instructions := Parser2.Parse(LongEquation);
    end;

  Writeln('Parsing: ' + Watch.ToString);
  Watch.Reset;
    for I  := 1 to IterationCount do
      Instructions.Evaluate;
  Writeln('Evaluation: ' + Watch.ToString);
  Instructions.Free;
  Parser2.Free;
end;

procedure TestVariables;
var
  Parser: TCPParser;
  Term: TCPTerm;
  Components: TObjectList;
  I, J: Integer;
begin
  Parser := TCPParser.Create;
  Term := TCPVariableTerm.Create(Parser, 'a1+a2+a3+a4+a5+a6+a7');
  Parser.Variables['a1'].Term := TCPVariableTerm.Create(Parser, 'a2');
  Parser.Variables['a2'].Term := TCPVariableTerm.Create(Parser, 'a1');
  Parser.Variables['a3'].Term := TCPVariableTerm.Create(Parser, 'a1');
  Parser.Variables['a4'].Term := TCPVariableTerm.Create(Parser, 'a1');
  Parser.Variables['a5'].Term := TCPVariableTerm.Create(Parser, 'a2');
  Parser.Variables['a6'].Term := TCPVariableTerm.Create(Parser, 'a3');
  Parser.Variables['a7'].Term := TCPVariableTerm.Create(Parser, 'a1');
  //Writeln(Term.Instructions.Evaluate);
  Watch.Reset;
  Parser.Variables.Validate;
  Writeln(Watch.ToString);
  Term.Free;
  Parser.Free;
end;

procedure TestTokenizer;
var
  Text: string;
  Test: TCPParser;
  Instructions: TCPInstructionList;
begin
  Text := LongEquation;
  Test := TCPParser.Create;
  Instructions := Test.Parse(Text);
  //Instructions.DumpBytecode;
  Writeln('---');
  Writeln('= ' + FloatToStr(Instructions.Evaluate));
  Instructions.Free;
  Test.Free;
end;

//procedure TestStringHashMap;
//var
//  HashMap: TCPStringHashMap;
//  Text: string;
//begin
//  HashMap := TCPStringHashMap.Create();
//  Text := 'This,is,a,test,string';
//  HashMap.Values['Test'] := TCPTextSequence.Create(@Text, 1, 5);
//  HashMap.Values['bla'] := TCPTextSequence.Create(@Text, 6, 8);
//  HashMap.Values['narf'] := TCPTextSequence.Create(@Text, 11, 15);
//  Writeln(HashMap.Values['Test'].ToString);
//  Writeln(HashMap.Values['bla'].ToString);
//  Writeln(HashMap.Values['narf'].ToString);
//  HashMap.Free;
//end;


function Mod1(X, B: Double): Double;
begin
  Result := x - round(x/b - 0.5) * b;
end;

function Mod2(X, B: Double): Double;
begin
  Result := x - b*int(x/b);
end;


procedure Main;
var
  Sequence: TCPTextSequence;
  Text: string;
  I, C: Integer;
  R: Double;
begin
  C := 10000000;
  Watch.Reset;
  for I := 0 to C - 1  do
    R := Int(I + 1.2);
  Writeln(Watch.ToString);
  Watch.Reset;
  for I := 0 to C - 1 do
    R := Trunc(I + 1.2);
  Writeln(Watch.ToString);
//  Text := 'This is a test';
//  Sequence := TCPTextSequence.Create(@Text, 1, Length(Text) + 1);
//  Assert(Length(Sequence.ToString) = Length(Text));
//  Writeln(Sizeof(TCPBytecodeInstruction));
//  TestVariables;
//  TestPerformance;
  //Sequence.Start := 0-+-++++--+-1;
  //TestTokenizer;
  //TestStringHashMap;
  //TestParser;
end;

var S: string;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
